package cn.darkhorse.ticket.service.impl;

import cn.darkhorse.exception.ServiceException;
import cn.darkhorse.ticket.pojo.MesCodeRules;
import cn.darkhorse.ticket.service.IRepeatCheckService;
import cn.darkhorse.ticket.service.MesCodeRulesService;
import cn.darkhorse.workflow.tool.BusinessConstants;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @description:
 * @author: mr.wang
 * @time: 2024/1/11 15:11
 */
@Service
public class RepeatCheckServiceImpl<T> implements IRepeatCheckService{
	
	
	@Resource
	private MesCodeRulesService codeRulesService;
	
	
	public static final String FIELD_ID = "id";
	public static final String FIELD_CODE = "code";
	public static final String FIELD_NAME = "name";
	
	IService isss;
	

	
	@Override
	public void repeatCode(IService iService,Long businessId,String code){
		boolean repeat = repeat(iService, businessId, code, null);
		if(!repeat){
			throw  new ServiceException("单据编码已重复添加！");
		}
	}
	
	@Override
	public String repeatAutoCode(IService iService,Long businessId,String businessType,String code,boolean isAuto){
		String newCode = code;
		if(isAuto){
			isss = iService;
			newCode = codeRulesService.updateCode(businessType);
			boolean repeat = repeat(iService, businessId, newCode, null);
			if(!repeat){
				newCode = getRepaetCode(businessType, businessId);
			}
		}else {
			boolean repeat = repeat(iService, businessId, code, null);
			if(!repeat){
				throw  new ServiceException("单据编码已重复添加！");
			}
		}
		return newCode.equals(code)?null:newCode;
	}
	
	@Override
	public void repeatName(IService iService,Long businessId,String name){
		boolean repeat = repeat(iService, businessId, null, name);
	}
	
	
	@Override
	public void repeatCodeAndName(IService iService, Long businessId, String code, String name) {
		boolean repeat = repeat(iService, businessId, code, name);
		if(!repeat){
			throw  new ServiceException("单据编码已重复添加！");
		}
	}
	
	@Override
	public String repeatAutoCodeAndName(IService iService,Long businessId,String businessType,String code,String name,boolean isAuto){
		String newCode = code;
		if(isAuto){
			isss = iService;
			newCode = codeRulesService.updateCode(businessType);
			boolean repeat = repeat(iService, businessId, newCode, name);
			if(!repeat){
				newCode = getRepaetCode(businessType, businessId);
			}
		}else {
			boolean repeat = repeat(iService, businessId, code, name);
			if(!repeat){
				throw  new ServiceException("单据编码已重复添加！");
			}
		}
		return newCode.equals(code)?null:newCode;
	}
	
	
	
	public boolean repeat(IService iService,Long businessId,String code,String name){
		QueryWrapper<T> queryWrapper = new QueryWrapper<>();
		if(StringUtils.isNotBlank(name)){
			if(null != businessId){
				queryWrapper.ne(FIELD_ID,businessId);
			}
			queryWrapper.eq(FIELD_NAME,name);
			// 判断业务表单是否存在
			T t = (T) iService.getOne(queryWrapper);
			if (null != t) {
				String nameT = fieldValue(t,FIELD_NAME);
				if(name.equals(nameT)){
					throw  new ServiceException("单据名称已重复添加！");
				}
			}
		}
		queryWrapper.clear();
		if(StringUtils.isNotBlank(code)){
			if(null != businessId){
				queryWrapper.ne(FIELD_ID,businessId);
			}
			queryWrapper.eq(FIELD_CODE,code);
			// 判断业务表单是否存在
			T t2 = (T) iService.getOne(queryWrapper);
			if(null != t2){
				String codeT = fieldValue(t2,FIELD_CODE);
				if(code.equals(codeT)){
					return false;
				}
			}
		}
	
		return true;
	}
	
	
	/**
	 * 获取字段值
	 * @param t
	 * @param field
	 * @return
	 */
	private String fieldValue(T t,String field){
		String value;
		try {
			//获取  无字段封掉
			Field codeField = t.getClass().getDeclaredField(BusinessConstants.toCamelCase(field));
			codeField.setAccessible(true);
			try {
				//获取字段 无字段封掉
				value = String.valueOf(codeField.get(t));
			} catch (IllegalAccessException e) {
				e.printStackTrace();
				throw new ServiceException(e.getMessage());
			}
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
			throw new ServiceException(e.getMessage());
		}
		return value;
	}
	
	
	/**
	 * 获取手动与自动重复后的编码
	 * @param key  编码识别码
	 */
	private String getRepaetCode(String key,Long id){
		List<String> result = getCode(key,id);
		codeRulesService.updateCodeByRepeat(key,Integer.valueOf(result.get(1)));
		return  result.get(0)+result.get(1);
	}
	
	private  List<String> getCode(String key,Long id){
		MesCodeRules rules = codeRulesService.getRules(key);
		String headValue = codeRulesService.getHeadRule(rules.getHeadRule());
		AtomicInteger ai = new AtomicInteger(rules.getIncreasingNumber());
		while (true){
			String serialNumber = String.format("%0"+rules.getDigit()+"d",ai.get());
			boolean b = repeat(isss,id,headValue + serialNumber,null);
			if(b){
				List<String> result = new ArrayList<>();
				result.add(headValue);
				result.add(serialNumber);
				return result;
			}
			ai.incrementAndGet();
		}
	}
	
	
}
